package com.imooc.juc;

import com.imooc.juc.utils.Ticket;

/**
 *  题目： 3个售票员  卖出  30票
 *  1   线程      操作      资源类
 *  2   标准：高内聚，低耦合
 *
 *
 * @Date:2021/10/26/22:27
 * @Description:
 */
public class SaleTicket {
    public static void main(String[] args) {

        Ticket ticket = new Ticket();



        new Thread(() ->{for (int i = 0; i < 30; i++) ticket.sale(); },"A").start();
        new Thread(() ->{for (int i = 0; i < 30; i++) ticket.sale(); },"B").start();
        new Thread(() ->{for (int i = 0; i < 30; i++) ticket.sale(); },"C").start();

//        //匿名内部类
//        new Thread(new Runnable() {
//            @Override
//            public void run() {
//                for (int i = 0; i < 30; i++) {
//                    ticket.sale();
//                }
//            }
//        }, "A").start();


    }
}

/*
为什么出现Lock？
当一个线程获取了对应的锁，并执行该代码块时，其他线程便只能一直等待，等待获取锁的线程释放锁，而这里获取锁的线程释放锁只会有两种情况：
1）获取锁的线程执行完了该代码块，然后线程释放对锁的占有；
2）线程执行发生异常，此时JVM会让线程自动释放锁。

那么如果这个获取锁的线程由于要等待IO或者其他原因（比如调用steep方法）被阻塞了，但是又没有释放锁，
其他线程便只能干巴巴地等待，试想一下，这多么影响程序执行效率。因此就需要有一种机制可以不让等待的
线程一直无期限地等待下去（比如只等待一定的时间或者能够响应中断），通过Lock就可以办到。

区别如下：
1. lock是一个接口，而在syncronized是java的一个关键字， syncronized是内置的语言实现：
2. syncronized 在发生异常的时候会释放占有的锁，因此不会出现死锁；而lock发生异常的时候，
    不会主动释放占有的锁， 必须手动unlock来释放锁，可能引起死锁的发生。（所以最好将同步代码块用 try catch包起来，在finally中释放锁）
3. lock等待锁的过程中可以用 interrupt来终端等待，而synchronized只能等待锁的释放，不能响应中断；

 */